﻿var Timer_State = {
    Start: 1,
    Stop: 2,
    Pause: 3
};

//expression 计时器要执行的脚本字符串
//interval 执行间隔 单位毫秒
//nMaxExeCount 执行次数 为 Number.POSITIVE_INFINITY 时不断执行
//bFirstExe 为true时先执行表达式然后再进行下一次计时，为false时先执行下一次的计时再执行表达式

function Timer(expression, interval, nMaxExeCount, bFirstExe) {


    if (Timer._Initialized == undefined) {

        //开始
        Timer.prototype.Start = function() {

            if (this.State == Timer_State.Start) return;
            this.State = Timer_State.Start;
            this.doStart();
        }

        Timer.prototype.doStart = function() {
            this.CreateExpressionTimer();
        }

        Timer.prototype.CreateExpressionTimer = function() {

            var exp = this.BuildExpression(this.Expression);
            this._Timer = setTimeout(exp, this.Interval);
        }

        //表达式执行完毕
        Timer.prototype.ExecuteComplete = function() {

            this.ExeCount++;

            if (this.MaxExeCount != Number.POSITIVE_INFINITY && this.ExeCount >= this.MaxExeCount) {
                this.Stop();
                return;
            }

            if (this.State == Timer_State.Start) this.CreateExpressionTimer();
        }

        //停止
        Timer.prototype.Stop = function() {

            if (this.State == Timer_State.Stop) return;
            this.State = Timer_State.Stop;
            this.doStop();

        }

        Timer.prototype.doStop = function() {

            this.ClearCheckPause();
            if (this._Timer == null) return;
            clearTimeout(this._Timer);
            this._Timer = null;
        }

        //暂停
        Timer.prototype.Pause = function(fCheckPause, checkInterval) {

            if (fCheckPause == null || typeof (fCheckPause) != "function") {
                throw "参数类型异常";
            }

            if (this.State == Timer_State.Stop) return;
            this.ClearCheckPause();

            this.State = Timer_State.Pause;
            this.CheckPauseHandler = fCheckPause;
            if (checkInterval == null) checkInterval = 500; 
            
            this.CheckInterval = checkInterval;

            this.doStop();

            this.doPause();
        }

        Timer.prototype.doPause = function() {

            this._CheckPauseTimer = setTimeout("Timer.CheckPause(" + this.Id + ");", this.CheckInterval);
        }

        Timer.prototype.CheckPause = function() {

            if (this.CheckPauseHandler == null) return;

            if (this.CheckPauseHandler()) {
                this.Resume();
            }
            else {
                this.doPause();
            }
        }

        Timer.prototype.ClearCheckPause = function() {
            if (this._CheckPauseTimer == null) return;
            clearTimeout(this._CheckPauseTimer);
            this._CheckPauseTimer = null;
            this.CheckPauseHandler = null;
        }

        //恢复
        Timer.prototype.Resume = function() {

            this.ClearCheckPause();
            if (this.State == Timer_State.Stop) return;
            
            this.Start();
        }

        Timer.prototype.BuildExpression = function(expression) {
            var str = "Timer.ExecuteComplete(" + this.Id + ");";
            var _expression = this.FirstExe ? (expression + ";" + str) : (str + expression);

            return _expression;
        }

        //释放资源
        Timer.prototype.Dispose = function() {

            this.Stop();
            this.Expression = null;
            this.CheckPauseHandler = null;
            Timer.Timers.Remove(this);
        }
    }


    if (interval == null || expression == null) {
        throw "缺少参数";
    }

    if (typeof (expression) != "string") {
        throw "参数类型不正确";
    }
    if (nMaxExeCount == null) nMaxExeCount = Number.POSITIVE_INFINITY;
    if (bFirstExe == null) bFirstExe = false;

    this.MaxExeCount = nMaxExeCount;
    this.ExeCount = 0;
    this.FirstExe = bFirstExe;
    this.Interval = interval;
    this.State = Timer_State.Stop;
    this._Timer = null;
    this.CheckInterval = 500;
    this.CheckPauseHandler = null;
    this._CheckPauseTimer = null;
    this.Id = Timer.GetNewId();
    this.Expression = expression;
    Timer.Timers.push(this);
}

//根据值取得索引
Array.prototype.IndexOf = function(oValue) {
    var count = this.length, value;


    for (var i = 0; i < count; i++) {
        if (this[i] == oValue) {
            return i;
        }
    }

    return -1;
}
//根据索引移除
Array.prototype.RemoveByIndex = function(iStartIndex, iDeleteCount) {
    if (iDeleteCount == null) iDeleteCount = 1;

    this.splice(iStartIndex, iDeleteCount);

    return this.length;
}

//移除项
Array.prototype.Remove = function(oValue) {
    var index = this.IndexOf(oValue);

    return this.RemoveByIndex(index);
}

Timer.Timers = new Array();

Timer.LastId = 0;
Timer.GetNewId = function() {

    ++Timer.LastId;

    return Timer.LastId;
}


Timer.GetTimerById = function(id) {

    var count = Timer.Timers.length;

    for (var i = 0; i < count; i++) {
        var timer = Timer.Timers[i];

        if (timer.Id == id) {
            return timer;
        }
    }

    return null;
}

Timer.ExecuteComplete = function(id) {

    var timer = Timer.GetTimerById(id);
    if (timer != null) timer.ExecuteComplete();
}

Timer.CheckPause = function(id) {

    var timer = Timer.GetTimerById(id);

    if (timer != null) timer.CheckPause();
}
